package com.ss.android.article.base;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.util.Base64;

import com.bytedance.common.utility.Logger;
import com.bytedance.common.utility.collection.WeakList;
import com.ss.android.article.base.feature.app.c.ImageManager;
import com.ss.android.common.applog.AppLog;
import com.ss.android.common.load.AsyncLoader;
import com.ss.android.common.util.NetworkUtils;
import com.ss.android.image.model.ImageUrl;
import com.ss.android.newmedia.util.AppUtil;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.zip.Inflater;

public class ImageProvider extends ContentProvider {
    public interface OnRemoteImageLoadedListener {
        void onRemoteImageLoaded(long itemId, int index,
                                 boolean validResult, boolean isOrigin);
    }

    static final class ImageAsyncLoader
            implements AsyncLoader.LoaderProxy<String, String, RequestInfo, Void, String> {
        private Context mContext;
        private ImageManager mImageManager;

        public ImageAsyncLoader(Context context, ImageManager imageManager) {
            this.mContext = context;
            this.mImageManager = imageManager;
        }

        private String fetchImage(String key, String param, RequestInfo requestInfo) {
            if (key == null) {
                return null;
            }

            try {
                String externalCacheFilePath = this.mImageManager.getExternalCacheFile(key);
                if (new File(externalCacheFilePath).isFile()) {
                    return externalCacheFilePath;
                }
                String internalCacheFilePath = this.mImageManager.getInternalCacheFile(key);
                if (new File(internalCacheFilePath).isFile()) {
                    return internalCacheFilePath;
                }
                if (!NetworkUtils.isNetworkAvailable(this.mContext)) {
                    return null;
                }
                if (AppUtil.downloadImage(
                        this.mContext,
                        -1,
                        param,
                        requestInfo.imageUrlList,
                        this.mImageManager.getExternalImageSaveDir(key),
                        this.mImageManager.getInternalImageSaveDir(key),
                        ImageManager.getCacheFileName(key),
                        null,
                        null,
                        null)) {
                    if (new File(externalCacheFilePath).isFile()) {
                        return externalCacheFilePath;
                    }
                    if (new File(internalCacheFilePath).isFile()) {
                        return internalCacheFilePath;
                    } else {
                        return null;
                    }
                }
                if (!Logger.debug()) {
                    return null;
                }
                Logger.v("ImageProvider", "fetch image fail: " + param);
            } catch (Throwable throwable) {
                if (!Logger.debug()) {
                    return null;
                }
                Logger.v("ImageProvider", "fetch image exception: " + throwable);
            }

            return null;
        }

        public final String doInBackground(String key, String param, RequestInfo extra) {
            return this.fetchImage(key, param, extra);
        }

        public final void onLoaded(String key, String param, RequestInfo extra, String result) {
            boolean validResult = result != null;
            Iterator<OnRemoteImageLoadedListener> iterator = ImageProvider.sOnRemoteImageLoadedListenerList.iterator();
            while (iterator.hasNext()) {
                OnRemoteImageLoadedListener onRemoteImageLoadedListener = iterator.next();
                if (onRemoteImageLoadedListener == null) {
                    continue;
                }
                if (extra == null) {
                    continue;
                }
                onRemoteImageLoadedListener.onRemoteImageLoaded(extra.itemId, extra.index, validResult, extra.origin);
            }
        }
    }

    static final class RequestInfo {
        public final long itemId;
        public final int index;
        public final List<ImageUrl> imageUrlList;
        public final boolean origin;

        public RequestInfo(long itemId, int index, List<ImageUrl> imageUrlList, boolean origin) {
            this.itemId = itemId;
            this.index = index;
            this.imageUrlList = imageUrlList;
            this.origin = origin;
        }

        public final boolean equals(Object obj) {
            return obj instanceof RequestInfo
                    && this.itemId == ((RequestInfo) obj).itemId
                    && this.index == ((RequestInfo) obj).index
                    && this.origin == ((RequestInfo) obj).origin;
        }

        public final int hashCode() {
            return ((int) (this.itemId << 4 | (((long) this.index))));
        }

        public final String toString() {
            return "RequestInfo(" + this.itemId + " " + this.index + ")";
        }
    }

    static WeakList<OnRemoteImageLoadedListener> sOnRemoteImageLoadedListenerList = new WeakList<>();
    private static byte[] buffer = new byte[4096];
    private static ImageAsyncLoader sImageAsyncLoader = null;
    private static AsyncLoader sAsyncLoader;

    /**
     * @param context
     * @param uri     content://com.ss.android.article.base.ImageProvider1212/getimage/origin/eJy00jEOgyAUxvG7vFnFKBogaXqQpgMqKi2I4qOL8e5NOrjYyehOvh_55y3gvO70AGKB4M0M4gE94igIGbMyQRdQS6dtl9TOEiN9pwi6Oa6HWMfT55WZifJ3SrgqVMZZlTayoFQyqShrGWO0anKe5-W99c7eGoVSG4g2orhc4BcJzwiC1yDg-B6sEWAfbPUv_u7fv5eXljld2N3PScLW_vgerOs3AAD__5xT9KE=/7047682253542916646/0
     * @return
     */
    private static File requestImage(Context context, Uri uri) {
        if (Logger.debug()) {
            Logger.v("ImageProvider", "== request image " + uri);
        }

        if (uri == null) {
            return null;
        }

        List<String> pathSegments = uri.getPathSegments();
        if (pathSegments == null) {
            return null;
        }

        int size = pathSegments.size();
        if (size < 3) {
            return null;
        }

        String firstSegment = pathSegments.get(0);
        String secondSegment = pathSegments.get(1);
        boolean isOrigin = "origin".equals(secondSegment);
        String thirdSegment = pathSegments.get(2);
        int v9;
        if ("image".equals(firstSegment)) {
            if (size == 3) {
                v9 = 0;
            } else {
                return null;
            }
        } else if ("getimage".equals(firstSegment)) {
            if (size == 5) {
                if ("none".equals(secondSegment)) {
                    v9 = 0;
                } else {
                    v9 = 1;
                }
            } else {
                return null;
            }
        } else {
            return null;
        }

        try {
            ArrayList originUrlList = new ArrayList();
            ArrayList thumbUrlList = new ArrayList();
            byte[] bytes = Base64.decode(thirdSegment, 8);
            Inflater inflater = new Inflater();
            inflater.setInput(bytes);
            synchronized (ImageProvider.buffer) {
                int length = inflater.inflate(ImageProvider.buffer);
                inflater.end();
                if (length > 0 && length < 4096) {
                    String decode = new String(ImageProvider.buffer, 0, length, "UTF-8");
                    JSONObject jo = new JSONObject(decode);
                    JSONObject originJo = jo.getJSONObject("origin");
                    String originUri = originJo.getString("uri");
                    String originKey = com.bytedance.common.utility.aa.md5(originUri);
                    JSONArray urlsJa = originJo.getJSONArray("urls");
                    int urlLength = urlsJa.length();
                    for (int i = 0; i < urlLength; ++i) {
                        String url = urlsJa.getString(i);
                        if (!android.support.design.a.isTextEmpty(url)) {
                            originUrlList.add(new ImageUrl(url));
                        }
                    }

                    JSONObject thumbJo = jo.getJSONObject("thumb");
                    String thumbUri = thumbJo.getString("uri");
                    String thumbKey = com.bytedance.common.utility.aa.md5(thumbUri);
                    JSONArray thumbUrlsJa = thumbJo.getJSONArray("urls");
                    int urlLength2 = thumbUrlsJa.length();
                    for (int i = 0; i < urlLength2; ++i) {
                        String thumbUrl = thumbUrlsJa.getString(i);
                        if (!android.support.design.a.isTextEmpty(thumbUrl)) {
                            thumbUrlList.add(new ImageUrl(thumbUrl));
                        }
                    }
                    ImageManager imageManager = new ImageManager(context);
                    File originImageFile = null;
                    if (originKey != null) {
                        File externalCacheFile = new File(imageManager.getExternalCacheFile(originKey));
                        if (externalCacheFile.isFile()) {
                            originImageFile = externalCacheFile;
                        } else {
                            File internalCacheFile = new File(imageManager.getInternalCacheFile(originKey));
                            if (internalCacheFile.isFile()) {
                                originImageFile = internalCacheFile;
                            }
                        }
                    }
                    if (isOrigin && originImageFile != null) {
                        return originImageFile;
                    }

                    File thumbImageFile = null;
                    if (thumbKey != null) {
                        File externalCacheFile = new File(imageManager.getExternalCacheFile(thumbKey));
                        if (externalCacheFile.isFile()) {
                            thumbImageFile = externalCacheFile;
                        } else {
                            File internalCacheFile = new File(imageManager.getInternalCacheFile(thumbKey));
                            if (internalCacheFile.isFile()) {
                                thumbImageFile = internalCacheFile;
                            }
                        }
                    }

                    if (!isOrigin && thumbImageFile != null) {
                        return thumbImageFile;
                    }

                    if (thumbImageFile != null) {
                        return thumbImageFile;
                    }

                    if (v9 == 0) {
                        return null;
                    }
                    boolean origin;
                    ArrayList<ImageUrl> urlList;
                    String imageUri;
                    String imageKey;

                    if (isOrigin) {
                        origin = true;
                        urlList = originUrlList;
                        imageUri = originUri;
                        imageKey = originKey;
                    } else {
                        origin = false;
                        urlList = thumbUrlList;
                        imageUri = thumbUri;
                        imageKey = thumbKey;
                    }
                    long itemId = Long.parseLong(pathSegments.get(3));
                    int index = Integer.parseInt(pathSegments.get(4));
                    if (thumbUri != null && itemId > 0 && index >= 0) {
                        if (Logger.debug()) {
                            Logger.v("ImageProvider", "image cache miss, inqueue: " + imageUri);
                        }
                        synchronized (ImageProvider.class) {
                            if (ImageProvider.sImageAsyncLoader == null) {
                                ImageProvider.sImageAsyncLoader = new ImageAsyncLoader(context, imageManager);
                                ImageProvider.sAsyncLoader = new AsyncLoader(80, 2, ImageProvider.sImageAsyncLoader, true);
                            }
                        }
                        ImageProvider.sAsyncLoader.addTask(imageKey, imageUri, new RequestInfo(itemId, index, urlList, origin), null);
                        return null;
                    }
                    return null;
                }
                return null;
            }
        } catch (Exception exception) {
            Logger.w("ImageProvider", "proivde image exception: " + exception);
            AppLog.x();
        }
        return null;
    }

    public static void addOnRemoteImageLoadedListener(OnRemoteImageLoadedListener onRemoteImageLoadedListener) {
        ImageProvider.sOnRemoteImageLoadedListenerList.add(onRemoteImageLoadedListener);
    }

    public static void remoteOnRemoteImageLoadedListener(OnRemoteImageLoadedListener arg2) {
        ImageProvider.sOnRemoteImageLoadedListenerList.remove(arg2);
        if (ImageProvider.sOnRemoteImageLoadedListenerList.weakHashMap.isEmpty()) {
            AsyncLoader asyncLoader = ImageProvider.sAsyncLoader;
            if (asyncLoader != null) {
                asyncLoader.clearQueue();
                Logger.d("ImageProvider", "clear queue");
            }
        }
    }

    public int delete(Uri uri, String arg3, String[] arg4) {
        return 0;
    }

    public String getType(Uri arg2) {
        return null;
    }

    public Uri insert(Uri arg2, ContentValues arg3) {
        return null;
    }

    public boolean onCreate() {
        return false;
    }

    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        File file = ImageProvider.requestImage(this.getContext(), uri);
        ParcelFileDescriptor fd = file != null ? ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY) : null;
        return fd;
    }

    public Cursor query(Uri arg2, String[] arg3, String arg4, String[] arg5, String arg6) {
        return null;
    }

    public int update(Uri arg2, ContentValues arg3, String arg4, String[] arg5) {
        return 0;
    }
}

